package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.AddressBookBusinessException;

import com.sky.exception.OrderBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.service.ShoppingCartService;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.websocket.WebSocketServer;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private ShoppingCartService shoppingCartService;
    @Autowired
    private OrderDetailMapper orderDetailMapper;

    /**
     * 创建订单
     *
     * @param ordersSubmitDTO
     * @return 1.根据地址簿id查询地址簿信息为空抛异常
     * 2.根据userid查询购物车数据,为空抛异常
     * 3.创建订单对象,并赋值,插入订单表数据
     * 4.创建订单明细表对象,用购物车中的数据赋值
     * 5.插入订单明细表中
     * 6.清空购物车
     */
    @Override
    @Transactional
    public OrderSubmitVO orderCreat(OrdersSubmitDTO ordersSubmitDTO) {

        //* 1.根据地址簿id查询地址簿信息为空抛异常
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if (addressBook == null) {
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }
        //* 2.根据userid查询购物车数据,为空抛异常
       /* ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(BaseContext.getCurrentId());
        List<ShoppingCart> shoppingCarts = shoppingCartMapper.list(shoppingCart);*/
        List<ShoppingCart> shoppingCarts = shoppingCartService.select();
        if (shoppingCarts == null || shoppingCarts.size() == 0) {
            throw new AddressBookBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }
        //* 3.创建订单对象,并赋值,插入订单表数据
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO, orders);
        orders.setNumber(String.valueOf(System.currentTimeMillis()));//赋值订单业务id 时间戳
        orders.setStatus(Orders.PENDING_PAYMENT);//设置订单状态
        orders.setUserId(BaseContext.getCurrentId());//设置用户id
        orders.setOrderTime(LocalDateTime.now());//设置下单时间
        orders.setPayStatus(Orders.UN_PAID);//设置支付状态
        orders.setPhone(addressBook.getPhone());
        orders.setAddress(addressBook.getDetail());
        orders.setConsignee(addressBook.getConsignee());
        orderMapper.insert(orders);

        // * 4.创建订单明细表对象,用购物车中的数据赋值
       /* List<OrderDetail> list = new ArrayList<>();
        for (ShoppingCart cart : shoppingCarts) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart,orderDetail,"id");
            orderDetail.setOrderId(orders.getId());
            list.add(orderDetail);
        }*/

        //map类型转换
        List<OrderDetail> list = shoppingCarts.stream().map(shoppingCart -> {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(shoppingCart, orderDetail, "id");
            orderDetail.setOrderId(orders.getId());
            return orderDetail;
        }).collect(Collectors.toList());

        //5.插入订单明细表中
        orderDetailMapper.insert(list);
        //6.清空购物车
        shoppingCartService.delete();
        //7.封装vo
        /*OrderSubmitVO orderSubmitVO = new OrderSubmitVO();
        orderSubmitVO.setId(orders.getId());
        orderSubmitVO.setOrderNumber(orders.getNumber());
        orderSubmitVO.setOrderTime(orders.getOrderTime());
        orderSubmitVO.setOrderAmount(orders.getAmount());*/
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder().id(orders.getId()).
                orderAmount(orders.getAmount())
                .orderTime(orders.getOrderTime()).
                orderNumber(orders.getNumber()).build();
        return orderSubmitVO;
    }

    /**
     * 用户查询历史订单
     *
     * @param page
     * @param pageSize
     * @param status
     * @return 1.获取用户id
     * 2.根据用户id,状态动态查询所有订单
     * 3.根据订单id查询订单明细表
     * 4.封装返回结果
     */
    @Override
    public PageResult HistoricalOrderInquiry(Integer page, int pageSize, Integer status) {
        //开启分页
        PageHelper.startPage(page, pageSize);
        Long userId = BaseContext.getCurrentId();
        //封装分页查询数据
        OrdersPageQueryDTO ordersDTO = new OrdersPageQueryDTO();
        ordersDTO.setUserId(userId);
        ordersDTO.setStatus(status);
        //分页,条件查询订单
        Page<OrderVO> orderVos = orderMapper.pageQueryOrderVo(ordersDTO);


       /* Page<Orders> orders = orderMapper.selectPage(ordersDTO);
        //List<OrderVO> list = new ArrayList<>();
        //非空判断

        if (orders == null && orders.getTotal() == 0) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
            List<OrderVO> list = orders.stream().map(orders1 -> {
                OrderVO orderVO = new OrderVO();
                Long id = orders1.getId();
                //查询订单明细表
                List<OrderDetail> orderDetails = orderDetailMapper.selectByOrderId(id);
                BeanUtils.copyProperties(orders1, orderVO);
                orderVO.setOrderDetailList(orderDetails);
                return orderVO;
            }).collect(Collectors.toList());*/


           /* for (Orders order : orders) {
                OrderVO orderVO = new OrderVO();
                Long id = order.getId();
                //查询订单明细表
                List<OrderDetail> orderDetails = orderDetailMapper.selectByOrderId(id);
                BeanUtils.copyProperties(order, orderVO);
                orderVO.setOrderDetailList(orderDetails);
                list.add(orderVO);
            }*/

        //3.根据订单id查询订单明细表

        return new PageResult(orderVos.getTotal(), orderVos);
    }

    /**
     * 用户查询订单详情
     *
     * @param id
     * @return
     */

    public OrderVO selectWithOrderDetail(Long id) {
       /* //通过订单id查询订单
        Orders orders = orderMapper.selectById(id);
       //通过订单id查询订单明细表
        List<OrderDetail> orderDetails = orderDetailMapper.selectByOrderId(id);

        //封装返回结果
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orders, orderVO);
        orderVO.setOrderDetailList(orderDetails);*/
        OrderVO orderVO = orderMapper.getOrderById(id);
        return orderVO;
    }

    /**
     * 用户取消订单
     *
     * @param id 1.查询订单
     *           2.获取订单的状态
     *           3.判断状态是否满足条件
     *           4.
     */
    @Override
    public void cancelOrder(Long id) {
        //1.查询订单
        Orders orders = orderMapper.selectById(id);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        //2.获取订单的状态
        Integer status = orders.getStatus();
        if (status > 2) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        //如果状态为待接单，需要给用户退款
        if (orders.getStatus().equals(Orders.TO_BE_CONFIRMED)) {
            //支付状态修改为 退款
            orders.setPayStatus(Orders.REFUND);
        }
        // 更新订单状态、取消原因、取消时间
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelReason("用户取消");
        orders.setCancelTime(LocalDateTime.now());
        orderMapper.update(orders);
    }

    /**
     * 再来一单
     *
     * @param id 1.根据id查询订单详细表中的数据
     *           2.创建购物车对象
     *           3.将数据考培到购物车对象中
     *           4.给购物车数据中的userid
     *           4.将数据添加到购物车表中
     */
    @Override
    public void againOrder(Long id) {
        //1.根据id查询订单详细表中的数据
        List<OrderDetail> orderDetails = orderDetailMapper.selectByOrderId(id);
        //2.创建购物车对象
        //3.将数据考培到购物车对象中
        List<ShoppingCart> list = orderDetails.stream().map(orderDetail -> {
            ShoppingCart shoppingCart = new ShoppingCart();
            BeanUtils.copyProperties(orderDetail,shoppingCart);
            //给购物车的userId赋值
            shoppingCart.setCreateTime(LocalDateTime.now());
            shoppingCart.setUserId(BaseContext.getCurrentId());
            return shoppingCart;
        }).collect(Collectors.toList());
        //List<ShoppingCart> list = new ArrayList<>();

       /* for (OrderDetail orderDetail : orderDetails) {
            ShoppingCart shoppingCart = new ShoppingCart();
            BeanUtils.copyProperties(orderDetail, shoppingCart);
            shoppingCart.setCreateTime(LocalDateTime.now());
            shoppingCart.setUserId(BaseContext.getCurrentId());
            list.add(shoppingCart);
        }*/
        shoppingCartMapper.insertOrderDetails(list);
    }

    /**
     * 管理端订单搜索
     *
     * @param
     * @return 1.
     */
    @Override
    public PageResult selectConditions(OrdersPageQueryDTO ordersPageQuer) {
        //开启分页查询
        PageHelper.startPage(ordersPageQuer.getPage(), ordersPageQuer.getPageSize());
        Page<OrderVO> orderVOPage = orderMapper.pageQueryOrderVo(ordersPageQuer);
        List<OrderVO> list = orderVOPage.stream().map(orderVO -> {
            //通过每个订单id查询对应的订单明细表
            List<OrderDetail> orderDetails = orderVO.getOrderDetailList();
            List<String> orderDishList = orderDetails.stream().map(orderDetail -> {
                String orderDish = orderDetail.getName() + "*" + orderDetail.getNumber() + ";";
                return orderDish;
            }).collect(Collectors.toList());

            String join = String.join("", orderDishList);
            //调用方法把每个订单对应的订单明细表中的菜品明细及数量拼接成一个字符串
            // String join = getstring(orderDetails);
            //封装vo中的数据并返回
            orderVO.setOrderDetailList(orderDetails);
            orderVO.setOrderDishes(join);
            return orderVO;
        }).collect(Collectors.toList());

        //筛选订单,获取返回结果
        //Page<Orders> page = orderMapper.selectPage(ordersPageQuer);
        //搜索内容为空,提示未找到相关订单
        /*if (page == null || page.getTotal() == 0){
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }*/

       /* List<OrderVO> list = page.stream().map(order -> {

            OrderVO orderVO = new OrderVO();
            BeanUtils.copyProperties(order, orderVO);
            //通过每个订单id查询对应的订单明细表
            List<OrderDetail> orderDetails = orderDetailMapper.selectByOrderId(order.getId());
            //调用方法把每个订单对应的订单明细表中的菜品明细及数量拼接成一个字符串
            String join = getstring(orderDetails);
            //封装vo中的数据并返回
            orderVO.setOrderDetailList(orderDetails);
            orderVO.setOrderDishes(join);
            return orderVO;
        }).collect(Collectors.toList());*/


  /*  List<OrderVO> list = new ArrayList<>();
        List<Orders> orders = page.getResult();*/

      /*  for (Orders order : orders) {
            OrderVO orderVO = new OrderVO();
            BeanUtils.copyProperties(order, orderVO);
            List<OrderDetail> orderDetails = orderDetailMapper.selectByOrderId(order.getId());
            List<String> orderDishList = new ArrayList<>();
            for (OrderDetail orderDetail : orderDetails) {
                String orderDish = orderDetail.getName() + "*" + orderDetail.getNumber() + ";";
                orderDishList.add(orderDish);
            }
            String join = String.join("", orderDishList);
            orderVO.setOrderDetailList(orderDetails);
            orderVO.setOrderDishes(join);
            list.add(orderVO);
        }*/

        return new PageResult(orderVOPage.getTotal(),list);
    }

    public String getstring(List<OrderDetail> orderDetails){
        List<String> orderDishList = orderDetails.stream().map(orderDetail -> {
            String orderDish = orderDetail.getName() + "*" + orderDetail.getNumber() + ";";
            return orderDish;
        }).collect(Collectors.toList());

      /*  List<String> orderDishList = new ArrayList<>();
        for (OrderDetail orderDetail : orderDetails) {
            String orderDish = orderDetail.getName() + "*" + orderDetail.getNumber() + ";";
            orderDishList.add(orderDish);
        }*/
        //把集合转换成字符串返回
        String join = String.join("", orderDishList);
        return join;
    }

    /**
     * 各个状态的订单数量统计
     * @return
     */
    @Override
    public OrderStatisticsVO countByStatus() {
        //根据状态查询出,待接单,待派送,派送中的订单数量
        Integer toBeConfirmed = orderMapper.countStatus(Orders.TO_BE_CONFIRMED);
        Integer confirmed = orderMapper.countStatus(Orders.CONFIRMED);
        Integer deliveryInProgress = orderMapper.countStatus(Orders.DELIVERY_IN_PROGRESS);
        //封装vo,返回结果
        OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();
        orderStatisticsVO.setToBeConfirmed(toBeConfirmed);
        orderStatisticsVO.setConfirmed(confirmed);
        orderStatisticsVO.setDeliveryInProgress(deliveryInProgress);

        return orderStatisticsVO;
    }

    /**
     * 查询订单详情
     * @param id
     * @return
     */
    @Override
    public OrderVO selectOrderDetail(Long id) {
        //通过id查询订单
      /*  Orders orders = orderMapper.selectById(id);
        List<OrderDetail> orderDetails = orderDetailMapper.selectByOrderId(id);*/
        //封装vo
       /* OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orders,orderVO);
        orderVO.setOrderDetailList(orderDetails);*/
        OrderVO orderVO = orderMapper.getOrderById(id);
        return orderVO;
    }

    /**
     * 管理端接单
     * @param
     */

    public void orderTaking(OrdersConfirmDTO ordersDTO) {
        //修改订单状态
        Orders orders = new Orders();
        orders.setId(ordersDTO.getId());
        orders.setStatus(Orders.CONFIRMED);
        orderMapper.update(orders);
    }

    /**
     * 管理端拒单
     * @param ordersRejectionDTO
     * 只有待接单的可以拒单
     */
    @Override
    public void ejectOrder(OrdersRejectionDTO ordersRejectionDTO) {
        Long id = ordersRejectionDTO.getId();
        Orders orders = orderMapper.selectById(id);
        Integer status = orders.getStatus();
        //判断状态是否为待接单,
        if (status == null ||status != Orders.TO_BE_CONFIRMED){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        Integer payStatus = orders.getPayStatus();
        //已支付需退款
        if (payStatus == Orders.PAID){
            orders.setPayStatus(Orders.REFUND);
        }
        //指定拒单原因
        orders.setStatus(Orders.CANCELLED);
        orders.setRejectionReason(ordersRejectionDTO.getRejectionReason());
        orders.setCancelTime(LocalDateTime.now());
        orderMapper.update(orders);

    }
    /**
     * 管理端取消订单
     */
    @Override
    public void cancelOrderAdmin(OrdersCancelDTO ordersCancelDTO) {
        //通过订单Id获取订单
        Long id = ordersCancelDTO.getId();
        Orders orders = orderMapper.selectById(id);
        //获取订单支付状态
        Integer payStatus = orders.getPayStatus();
        //已支付需退款
        if (payStatus == Orders.PAID){
            orders.setPayStatus(Orders.REFUND);
        }
        //指定取消原因
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelReason(ordersCancelDTO.getCancelReason());
        orders.setCancelTime(LocalDateTime.now());
        //更新数据
        orderMapper.update(orders);

    }

    /**
     * 派送订单
     * @param id
     */
    @Override
    public void handOutOrder(Long id) {
        Orders orders = orderMapper.selectById(id);
        Integer status = orders.getStatus();
        //判断是否为已接单状态的订单
        if (status == null || status != Orders.CONFIRMED){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        //更新订单状态
        orders.setStatus(Orders.DELIVERY_IN_PROGRESS);
        orderMapper.update(orders);
    }

    /**
     * 完成订单
     * @param id
     */
    @Override
    public void completeOrder(Long id) {
        Orders orders = orderMapper.selectById(id);
        Integer status = orders.getStatus();
        //判断是否为已接单状态的订单
        if (status == null || status != Orders.DELIVERY_IN_PROGRESS){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        //更新订单状态
        orders.setStatus(Orders.COMPLETED);
        //发送ws请求 提醒商家来单提醒

        orderMapper.update(orders);
    }
    /**
     * 用户催单
     *
     * @param id
     * @return
     */
    @Autowired
    private WebSocketServer webSocketServer;
    @Override
    public void reminder(Long id) {
        //判断订单是否存在
        Orders orders = orderMapper.selectById(id);
        //校验订单是否存在,并且状态为2
        if (orders == null ){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        //发送WS请求催单
        Map map = new HashMap();
        map.put("type",2);
        map.put("orderId",id);
        map.put("content","订单号: "+orders.getNumber());
        webSocketServer.sendToAllClient(JSON.toJSONString(map));

    }

}
